/*
 * @Author: lihaogn
 * @Date: 2021-06-02 22:47:46
 * @LastEditTime: 2022-05-28 13:04:56
 * @LastEditor: lihaogn
 * @Description: 用户 - service
 * @FilePath: \lix-admin-server\app\service\user.js
 */

const Service = require("egg").Service;
const commonUtils = require("../utils/commonUtils");

class UserService extends Service {
  /**
   * @description: 获取所有用户信息
   * @param {*}
   * @return {*}
   */
  async queryUsers() {
    const { app } = this;
    try {
      // ========= mysql 写法 =========
      // const res = await app.mysql.select("users", {
      //   columns: [
      //     "user_id",
      //     "user_name",
      //     "user_role",
      //     "user_mobile",
      //     "user_email",
      //     "user_status",
      //     "created_at",
      //     "updated_at",
      //   ],
      // });
      // return res;

      // ========= Sequelize 写法 =========
      const res = await app.model.User.findAll({
        attributes: { exclude: ["password", "roleId"] },
        include: { model: app.model.Role, as: "role" },
      });
      return res;
    } catch (err) {
      console.log(err);
      return false;
    }
  }
  /**
   * @author: lihaogn
   * @Date: 2021-12-06 20:42:26
   * @description: 分页查询用户列表
   * @param {*} page - 当前页
   * @param {*} size - 每页数据量
   * @return {*}
   */
  async queryUsersByPage(page, size) {
    const { app } = this;
    try {
      // ========= mysql 写法 =========
      // const res = await app.mysql.query(
      //   "SELECT SQL_CALC_FOUND_ROWS user_id,user_name,user_role,user_mobile,user_email,user_status,created_at,updated_at FROM users LIMIT ?,?",
      //   [(page - 1) * size, +size]
      // );
      // // 获取总条数
      // const total = await app.mysql.query("SELECT FOUND_ROWS()");
      // return { data: res, total: total[0]["FOUND_ROWS()"] };

      // ========= Sequelize 写法 =========
      const { count, rows } = await app.model.User.findAndCountAll({
        attributes: { exclude: ["password", "roleId"] },
        include: {
          model: app.model.Role,
          as: "role",
          through: {
            attributes: [], // 不需要关联表中的数据
          },
        },
        offset: (page - 1) * size,
        limit: +size,
      });
      return { data: rows, total: count };
    } catch (err) {
      console.log(err);
      return false;
    }
  }

  /**
   * @author: lihaogn
   * @Date: 2021-12-19 17:55:13
   * @description: 更新用户信息
   * @param {*} id - 用户id
   * @param {*} req - 请求体
   * @return {*}
   */
  async update(id, req) {
    const { app } = this;
    try {
      // 1 更新用户基本信息
      const res = await app.model.User.update(
        {
          name: req.username,
          realname: req.realname,
          mobile: req.mobile,
          email: req.email,
          status: req.status,
        },
        {
          where: {
            id: id,
          },
        }
      );
      // 2 查询角色信息
      const roles = await app.model.Role.findAll({
        where: {
          id: {
            [app.Sequelize.Op.or]: req.role,
          },
        },
      });
      // 3 关联用户与角色
      const user = await app.model.User.findByPk(id);
      let setRes = [];
      if (user) {
        setRes = await user.setRole(roles);
      }

      return res.length && setRes.length;
    } catch (error) {
      console.log(error);
      return false;
    }
  }

  /**
   * @description: 修改密码
   * @param {*} id
   * @param {*} req
   * @return {*}
   */
  async editPassword(id, req) {
    const { app } = this;
    const row = {
      password: req.password,
    };

    const options = {
      where: {
        id: id,
        password: req.oldPassword,
      },
    };

    try {
      const res = await app.mysql.update("users", row, options);

      return res.affectedRows;
    } catch (err) {
      console.log(err);
      return false;
    }
  }

  /**
   * @description: 修改用户状态
   * @param {*} id
   * @param {*} req
   * @return {*}
   */
  async editStatus(id, req) {
    const { app } = this;
    // 要改变的字段
    const row = {
      status: req.userStatus,
    };
    // 条件
    const options = {
      where: {
        id: id,
      },
    };

    try {
      const res = await app.mysql.update("users", row, options);

      return res.affectedRows;
    } catch (error) {
      console.log(error);
      return false;
    }
  }

  /**
   * 查询用户名是否存在
   * @param username
   * @returns {Promise<*|null>}
   */
  async queryUserByName(username) {
    const { app } = this;

    try {
      const res = await app.mysql.get("users", { name: username });
      return res;
    } catch (err) {
      console.log(err);
      return false;
    }
  }

  /**
   * @author: lihaogn
   * @Date: 2021-11-18 20:25:58
   * @description: 根据 id 查询用户信息
   * @param {*} id - 用户 id
   * @return {*}
   */
  async queryUserById(id) {
    const { app } = this;

    // try {
    //   const res = await app.mysql.select("users", {
    //     where: { id: id },
    //     columns: ["id", "name", "status"],
    //   });
    //   return res;
    // } catch (err) {
    //   console.log(err);
    //   return false;
    // }

    try {
      const user = await app.model.User.findByPk(id);
      if (user) {
        const allPermissions = {
          pages: [],
          actions: [],
        };
        // 获取用户关联的角色
        const roles = await user.getRole();
        if (roles && roles.length) {
          // 获取角色关联的权限
          const permissions = await Promise.all(
            roles.map((role) => role.getPermission())
          );
          const permissionArr = [];
          const permissionIdSet = new Set();
          permissions.forEach((p) => {
            p.forEach((pp) => {
              let permissionId = pp.dataValues.id;
              if (!permissionIdSet.has(permissionId)) {
                permissionIdSet.add(permissionId);
                permissionArr.push(pp.dataValues);
              }
            });
          });
          permissionArr.reduce(
            (prev, x) => {
              if (x.type === 1) {
                prev.pages.push({
                  id: x.id,
                  name: x.name,
                  mark: x.mark,
                  type: x.type,
                });
              } else if (x.type === 2) {
                prev.actions.push({
                  id: x.id,
                  name: x.name,
                  mark: x.mark,
                  type: x.type,
                });
              }
              return prev;
            },
            { pages: allPermissions.pages, actions: allPermissions.actions }
          );

          return {
            id: user.id,
            name: user.name,
            status: user.status,
            role: roles.map((role) => {
              return { id: role.id, name: role.name };
            }),
            permission: allPermissions,
          };
        }
        // 没有角色
        return {
          id: user.id,
          name: user.name,
          status: user.status,
          role: [],
          permission: allPermissions,
        };
      }
      // 没有查到用户
      return false;
    } catch (error) {
      console.log("查询用户信息失败：", error);
      return false;
    }
  }

  /**
   * 新增用户
   * @param req
   * @returns {Promise<null|*>}
   */
  async createUser(req) {
    const { app } = this;
    try {
      // ========= mysql 写法 =========
      // const res = await app.mysql.insert("users", {
      //   user_id: commonUtils.getUUID(),
      //   user_name: req.username,
      //   user_password: req.password,
      //   user_role: req.role,
      //   user_mobile: req.mobile,
      //   user_email: req.email,
      //   user_status: req.status,
      // });
      // return res.affectedRows;

      // ========= Sequelize 写法 =========
      // 1 查询角色信息
      const roles = await app.model.Role.findAll({
        where: {
          id: {
            [app.Sequelize.Op.or]: req.role,
          },
        },
      });
      //  2 新增用户
      const user = await app.model.User.create({
        id: commonUtils.getUUID(),
        name: req.username,
        realname: req.realname,
        password: req.password,
        mobile: req.mobile,
        email: req.email,
        status: req.status,
      });
      // 3 关联用户与角色
      await user.setRole(roles);
      return true;
    } catch (err) {
      console.log("err", err);
      return false;
    }
  }

  /**
   * @author: lihaogn
   * @Date: 2021-12-11 18:16:52
   * @description: 导入用户
   * @param {*} req
   * @return {*}
   */
  async importUser(req) {
    const { app } = this;

    const data = req.map((x) => {
      let obj = {};
      obj.id = commonUtils.getUUID();
      obj.name = x.userName;
      obj.realname = x.userRealname;
      obj.mobile = x.userMobile || "";
      obj.email = x.userEmail || "";
      obj.status = 1;

      return obj;
    });

    try {
      await app.model.User.bulkCreate([...data], {
        fields: ["id", "name", "realname", "mobile", "email", "status"],
      });
      return true;
    } catch (err) {
      console.log("错误：", err);
      let message = { title: "导入失败", content: "" };
      if (err.errors instanceof Array) {
        let errorObj = err.errors[0];
        if (errorObj.type === "unique violation") {
          if (errorObj.path === "name") {
            message.content = `用户名：‘${errorObj.value}’重复`;
          }
          return { message };
        }
      }

      return { message: "导入异常" };
    }
  }

  /**
   * @author: lihaogn
   * @Date: 2021-11-18 11:35:34
   * @description: 删除单个用户
   * @param {*} id - 用户id
   * @return {*}
   */
  async deleteOneUser(id) {
    const { app } = this;

    try {
      const res = await app.mysql.delete("users", {
        id,
      });

      return res.affectedRows;
    } catch (error) {
      return false;
    }
  }
}

module.exports = UserService;
